`include "PRV564Config.v"
`include "PRV564Define.v"
`timescale  1ns / 1ps
/*****************************************************************************************
 *    author : Jack's Team Xiaoyu HONG
 *    e-mail : 
 *    date   : 20210730
 *    desc   : PRV564 first version difftest framework
 *    version: 0000 (Orignal version)

**********************************************************************************************/
module SimTop(
  input         clock,
  input         reset,
  input  [63:0] io_logCtrl_log_begin,
  input  [63:0] io_logCtrl_log_end,
  input  [63:0] io_logCtrl_log_level,
  input         io_perfInfo_clean,
  input         io_perfInfo_dump,
  output        io_uart_out_valid,
  output [7:0]  io_uart_out_ch,
  output        io_uart_in_valid,
  input  [7:0]  io_uart_in_ch
  // ......
);/* verilator lint_off UNOPTFLAT */
/* verilator lint_off TIMESCALEMOD */
//-----------------Test bench global signal----------------------
    wire                 Kernel_CLKi;                                    //Kernel clock input
    wire                 Kernel_ARSTi;                                   //Kernel reset input (Async)

//-----------------Kernel Difftest Debug Information-------------------
    assign    Kernel_CLKi=clock;
    assign    Kernel_ARSTi=reset;

    wire Core_SRST;
//-----------------------FIB interface---------------------
    wire                ICache_FIB_WRENo,   DCache_FIB_WRENo;
    wire                ICache_FIB_REQo,    DCache_FIB_REQo;
    reg                 ICache_FIB_ACKi,    DCache_FIB_ACKi;
    wire [7:0]          ICache_FIB_IDo,     DCache_FIB_IDo;
    wire [7:0]          ICache_FIB_CMDo,    DCache_FIB_CMDo;
    wire [3:0]          ICache_FIB_BURSTo,  DCache_FIB_BURSTo;
    wire [3:0]          ICache_FIB_SIZEo,   DCache_FIB_SIZEo;
    wire [`PADR-1:0]    ICache_FIB_ADDRo,   DCache_FIB_ADDRo;    
    wire [`XLEN-1:0]    ICache_FIB_DATAo,   DCache_FIB_DATAo;
    //                  TLB FIB interface
    wire                ITLB_FIB_WRENo,     DTLB_FIB_WRENo;
    wire                ITLB_FIB_REQo,      DTLB_FIB_REQo;
    reg                 ITLB_FIB_ACKi,      DTLB_FIB_ACKi;
    wire [7:0]          ITLB_FIB_IDo,       DTLB_FIB_IDo;
    wire [7:0]          ITLB_FIB_CMDo,      DTLB_FIB_CMDo;
    wire [3:0]          ITLB_FIB_BURSTo,    DTLB_FIB_BURSTo;
    wire [3:0]          ITLB_FIB_SIZEo,     DTLB_FIB_SIZEo;
    wire [`PADR-1:0]    ITLB_FIB_ADDRo,     DTLB_FIB_ADDRo;    
    wire [`XLEN-1:0]    ITLB_FIB_DATAo,     DTLB_FIB_DATAo;

    wire [3:0]          FIB_select;
    //               FIB access port
    reg                 FIB_AQ_WREN;
    reg                 FIB_AQ_V;
    wire                FIB_AQ_FULL;
    reg [7:0]           FIB_AQ_ID;
    reg [7:0]           FIB_AQ_CMD;
    reg [3:0]           FIB_AQ_BURST;
    reg [3:0]           FIB_AQ_SIZE;
    reg [`PADR-1:0]     FIB_AQ_ADDR;
    reg [`XLEN-1:0]     FIB_AQ_DATA;
    //               FIB result port
    wire                FIB_RQ_V;
    wire [7:0]          FIB_RQ_ID;
    wire [7:0]          FIB_RQ_RPL;
    wire [`XLEN-1:0]    FIB_RQ_DATA;


reset_gen       RST_SYNC(
    .clk                        (Kernel_CLKi),
    .rst_async                  (Kernel_ARSTi),
    .rst_sync                   (Core_SRST)
);

PRV564_top #(
    .HART_ID        (8'h0)
    // ITLB_FIBID=8'h01,
    // DTLB_FIBID=8'h02,
    // ICACHE_FIBID=8'h03,
    // DCACHE_FIBID=8'h04
)PRV564_top(
    .GLB_CLKi                   (Kernel_CLKi),
    .GLB_ARSTi                  (Core_SRST),
//----------------Flexible Interconnection Bus----------
    .ITLB_FIB_WRENo             (ITLB_FIB_WRENo), 
    .DTLB_FIB_WRENo             (DTLB_FIB_WRENo),
    .ITLB_FIB_REQo              (ITLB_FIB_REQo),  
    .DTLB_FIB_REQo              (DTLB_FIB_REQo),
    .ITLB_FIB_ACKi              (ITLB_FIB_ACKi),  
    .DTLB_FIB_ACKi              (DTLB_FIB_ACKi),
    .ITLB_FIB_FULLi             (FIB_AQ_FULL), 
    .DTLB_FIB_FULLi             (FIB_AQ_FULL),
    .ITLB_FIB_IDo               (ITLB_FIB_IDo),   
    .DTLB_FIB_IDo               (DTLB_FIB_IDo),
    .ITLB_FIB_CMDo              (ITLB_FIB_CMDo),  
    .DTLB_FIB_CMDo              (DTLB_FIB_CMDo),
    .ITLB_FIB_BURSTo            (ITLB_FIB_BURSTo),
    .DTLB_FIB_BURSTo            (DTLB_FIB_BURSTo),
    .ITLB_FIB_SIZEo             (ITLB_FIB_SIZEo), 
    .DTLB_FIB_SIZEo             (DTLB_FIB_SIZEo),
    .ITLB_FIB_ADDRo             (ITLB_FIB_ADDRo), 
    .DTLB_FIB_ADDRo             (DTLB_FIB_ADDRo),    
    .ITLB_FIB_DATAo             (ITLB_FIB_DATAo),
    .DTLB_FIB_DATAo             (DTLB_FIB_DATAo),
    //             FIB result port
    .ITLB_FIB_IDi               (FIB_RQ_ID),
    .DTLB_FIB_IDi               (FIB_RQ_ID),
    .ITLB_FIB_RPLi              (FIB_RQ_RPL),  
    .DTLB_FIB_RPLi              (FIB_RQ_RPL),
    .ITLB_FIB_Vi                (FIB_RQ_V),
    .DTLB_FIB_Vi                (FIB_RQ_V),
    .ITLB_FIB_DATAi             (FIB_RQ_DATA),
    .DTLB_FIB_DATAi             (FIB_RQ_DATA),
//CPU Cache FIB
    .ICache_FIB_WRENo           (ICache_FIB_WRENo), 
    .DCache_FIB_WRENo           (DCache_FIB_WRENo),
    .ICache_FIB_REQo            (ICache_FIB_REQo),  
    .DCache_FIB_REQo            (DCache_FIB_REQo),
    .ICache_FIB_ACKi            (ICache_FIB_ACKi),  
    .DCache_FIB_ACKi            (DCache_FIB_ACKi),
    .ICache_FIB_FULLi           (FIB_AQ_FULL),
    .DCache_FIB_FULLi           (FIB_AQ_FULL),
    .ICache_FIB_IDo             (ICache_FIB_IDo),
    .DCache_FIB_IDo             (DCache_FIB_IDo),
    .ICache_FIB_CMDo            (ICache_FIB_CMDo),
    .DCache_FIB_CMDo            (DCache_FIB_CMDo),
    .ICache_FIB_BURSTo          (ICache_FIB_BURSTo),
    .DCache_FIB_BURSTo          (DCache_FIB_BURSTo),
    .ICache_FIB_SIZEo           (ICache_FIB_SIZEo), 
    .DCache_FIB_SIZEo           (DCache_FIB_SIZEo),
    .ICache_FIB_ADDRo           (ICache_FIB_ADDRo), 
    .DCache_FIB_ADDRo           (DCache_FIB_ADDRo),    
    .ICache_FIB_DATAo           (ICache_FIB_DATAo), 
    .DCache_FIB_DATAo           (DCache_FIB_DATAo),
    //               FIB result port
    .ICache_FIB_IDi             (FIB_RQ_ID),
    .DCache_FIB_IDi             (FIB_RQ_ID),
    .ICache_FIB_RPLi            (FIB_RQ_RPL),
    .DCache_FIB_RPLi            (FIB_RQ_RPL),
    .ICache_FIB_Vi              (FIB_RQ_V),
    .DCache_FIB_Vi              (FIB_RQ_V),
    .ICache_FIB_DATAi           (FIB_RQ_DATA), 
    .DCache_FIB_DATAi           (FIB_RQ_DATA),
//---------------Interrupt signal-------------------------
    .Kernel_MTIi                (Kernel_MTIi),          //YSYX210152_Machine mode timer interrupt
    .Kernel_MSIi                (Kernel_MSIi),          //YSYX210152_Machine mode software interrupt
    .Kernel_MEIi                (Kernel_MEIi),          //YSYX210152_Machine mode ext interrupt
    .Kernel_SEIi                (Kernel_SEIi),          //YSYX210152_Supervisior mode ext interrupt
    .Kernel_NMIPLi              (1'b0),                 //NO NMI is used!
    .Kernel_NMIEEi              (1'b0),
    .Kernel_NMIGi               (1'b0),
//--------------YSYX210152_Machine mode timer-----------------------
    .Kernel_MTIMEi              (Kernel_MTIMEi)	        //YSYX210152_Machine mode timer value in
);

//------------------------FIB bus arbtine----------------------
FIB_arb         FIB_arb
(
    .CLKi                       (Kernel_CLKi),
    .ARSTi                      (Core_SRST),
//-------------FIB master request-------------------
    .Master_REQ                 ({DCache_FIB_REQo, ICache_FIB_REQo, DTLB_FIB_REQo, ITLB_FIB_REQo}),
    .Master_ACK                 (FIB_select)
);
always@(*)begin
    case(FIB_select)
        4'b0001 : begin
                    FIB_AQ_WREN = ITLB_FIB_WRENo;
                    FIB_AQ_V    = ITLB_FIB_WRENo;
                    FIB_AQ_ID   = ITLB_FIB_IDo;
                    FIB_AQ_CMD  = ITLB_FIB_CMDo;
                    FIB_AQ_BURST= ITLB_FIB_BURSTo;
                    FIB_AQ_SIZE = ITLB_FIB_SIZEo;
                    FIB_AQ_ADDR = ITLB_FIB_ADDRo;
                    FIB_AQ_DATA = ITLB_FIB_DATAo;
                    ITLB_FIB_ACKi= 1'b1;
                    DTLB_FIB_ACKi= 1'b0;
                    ICache_FIB_ACKi=1'b0;
                    DCache_FIB_ACKi=1'b0;
                 end
        4'b0010 : begin
                    FIB_AQ_WREN = DTLB_FIB_WRENo;
                    FIB_AQ_V    = DTLB_FIB_WRENo;
                    FIB_AQ_ID   = DTLB_FIB_IDo;
                    FIB_AQ_CMD  = DTLB_FIB_CMDo;
                    FIB_AQ_BURST= DTLB_FIB_BURSTo;
                    FIB_AQ_SIZE = DTLB_FIB_SIZEo;
                    FIB_AQ_ADDR = DTLB_FIB_ADDRo;
                    FIB_AQ_DATA = DTLB_FIB_DATAo;
                    ITLB_FIB_ACKi= 1'b0;
                    DTLB_FIB_ACKi= 1'b1;
                    ICache_FIB_ACKi=1'b0;
                    DCache_FIB_ACKi=1'b0;
                 end
        4'b0100 : begin
                    FIB_AQ_WREN = ICache_FIB_WRENo;
                    FIB_AQ_V    = ICache_FIB_WRENo;
                    FIB_AQ_ID   = ICache_FIB_IDo;
                    FIB_AQ_CMD  = ICache_FIB_CMDo;
                    FIB_AQ_BURST= ICache_FIB_BURSTo;
                    FIB_AQ_SIZE = ICache_FIB_SIZEo;
                    FIB_AQ_ADDR = ICache_FIB_ADDRo;
                    FIB_AQ_DATA = ICache_FIB_DATAo;
                    ITLB_FIB_ACKi= 1'b0;
                    DTLB_FIB_ACKi= 1'b0;
                    ICache_FIB_ACKi=1'b1;
                    DCache_FIB_ACKi=1'b0;
                 end
        4'b1000 : begin
                    FIB_AQ_WREN = DCache_FIB_WRENo;
                    FIB_AQ_V    = DCache_FIB_WRENo;
                    FIB_AQ_ID   = DCache_FIB_IDo;
                    FIB_AQ_CMD  = DCache_FIB_CMDo;
                    FIB_AQ_BURST= DCache_FIB_BURSTo;
                    FIB_AQ_SIZE = DCache_FIB_SIZEo;
                    FIB_AQ_ADDR = DCache_FIB_ADDRo;
                    FIB_AQ_DATA = DCache_FIB_DATAo;
                    ITLB_FIB_ACKi= 1'b0;
                    DTLB_FIB_ACKi= 1'b0;
                    ICache_FIB_ACKi=1'b0;
                    DCache_FIB_ACKi=1'b1;
                 end
        default: begin
                    FIB_AQ_WREN = 1'b0;
                    FIB_AQ_V    = 1'b0;
                    FIB_AQ_ID   = 'hx;
                    FIB_AQ_CMD  = 'hx;
                    FIB_AQ_BURST= 'hx;
                    FIB_AQ_SIZE = 'hx;
                    FIB_AQ_ADDR = 'hx;
                    FIB_AQ_DATA = 'hx;
                    ITLB_FIB_ACKi= 1'b0;
                    DTLB_FIB_ACKi= 1'b0;
                    ICache_FIB_ACKi=1'b0;
                    DCache_FIB_ACKi=1'b0;
                 end
    endcase
end

//    reg                 ;
wire [31:0]SRAM_RAddr;
wire [31:0]SRAM_WAddr;
wire [7:0]SRAM_WBMask;
wire [63:0]SRAM_WMask;
wire [63:0]SRAM_WData;
wire SRAM_CE;
wire [63:0]SRAM_RData;
FIB_L1_Test FIB_Host(
    // global input
    .VFIBi_CLK(clock),
    .VFIBi_ARST(reset),
    // master request
    .VFIBi_WREN(FIB_AQ_WREN),
    .VFIBi_ID(FIB_AQ_ID),//FIB_AQ_V
    .VFIBi_CMD(FIB_AQ_CMD),
    .VFIBi_BURST(FIB_AQ_BURST),
    .VFIBi_SIZE(FIB_AQ_SIZE),
    .VFIBi_ADDR(FIB_AQ_ADDR),
    .VFIBi_DATA(FIB_AQ_DATA),
    .VFIBo_FULL(FIB_AQ_FULL),
    .VFIBo_V(FIB_RQ_V),
    .VFIBo_ID(FIB_RQ_ID),
    .VFIBo_RPL(FIB_RQ_RPL),
    .VFIBo_DATA(FIB_RQ_DATA),
    .SRAM_RAddr(SRAM_RAddr),
    .SRAM_WAddr(SRAM_WAddr),
    .SRAM_WBMask(SRAM_WBMask),
    .SRAM_WData(SRAM_WData),
    .SRAM_CE(SRAM_CE),
    .SRAM_RData(SRAM_RData)
);
assign SRAM_WMask=  {
                    {8{SRAM_WBMask[7]}},
                    {8{SRAM_WBMask[6]}},
                    {8{SRAM_WBMask[5]}},
                    {8{SRAM_WBMask[4]}},
                    {8{SRAM_WBMask[3]}},
                    {8{SRAM_WBMask[2]}},
                    {8{SRAM_WBMask[1]}},
                    {8{SRAM_WBMask[0]}}
                };
    assign SRAM_RData=ram_read_helper(SRAM_CE,SRAM_RAddr-(32'h80000000>>3));
always @(posedge clock) 
    ram_write_helper(SRAM_WAddr-(32'h80000000>>3),SRAM_WData,SRAM_WMask,SRAM_CE);
endmodule
